/*
 * Copyright (c) 2010, 2012 Luan Nguyen Thanh. All rights reserved.
 * 
 * This code is written by Luan Nguyen Thanh, with any partners involved.
 * The use of this code should not be permitted!
 * If you want to use, please do contact me!
 */
package MyIM.client.view.form;

import MyIM.client.engine.Engine;
import MyIM.client.view.lnf.MetroStyle;
import MyIM.client.view.lnf.SegoeFont;
import MyIM.component.Friend;
import MyIM.utilities.Util;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.util.Date;
import java.util.Observable;
import java.util.Observer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import org.jdesktop.swingx.JXTextArea;

/**
 *
 * @author Luan Nguyen Thanh <tklarryonline@gmail.com>
 */
public class Dialog_Chat extends JFrame implements KeyListener, ActionListener,
        Observer {

    private static final int MAX_CHAT_LENGTH = 500;
    //
    private String currentUserDisplayName;
    private ImageIcon currentUserAvatar;
    private Friend friend;
    private JTextArea chatInput;
    private JTextPane chatDisplay;
    private JButton btnSendMsg;
    private JLabel lblTextCount;
    private Engine engine;

    public Dialog_Chat(Engine engine, String currentUserDisplayName,
            ImageIcon currentUserAvatar, Friend friend)
            throws HeadlessException {
        this.engine = engine;
        this.currentUserDisplayName = currentUserDisplayName;
        this.currentUserAvatar = new ImageIcon(currentUserAvatar.getImage().
                getScaledInstance(72, 72, Image.SCALE_SMOOTH));
        this.friend = friend;


        init();
        initListener();
    }

    private void init() {
        // Initializes the frame
        setTitle("Chat: " + friend.getDisplayName());
//        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setVisible(true);
        setIconImage(Util.makeIcon("Logo").getImage());

        chatInput = new JXTextArea("Type here to start chatting");
        chatInput.setColumns(23);
        chatInput.setLineWrap(true);
        chatInput.setRows(4);
        chatInput.setWrapStyleWord(true);

        lblTextCount = new JLabel("0/500");
        lblTextCount.setFont(SegoeFont.getSegoeUIFont("normal",
                12f));

        chatDisplay = new JTextPane();
        chatDisplay.setEditable(false);


        btnSendMsg = new JButton("Send");
        btnSendMsg.setActionCommand("send");
        btnSendMsg.setPressedIcon(new ImageIcon(new BufferedImage(1,
                1, BufferedImage.TYPE_INT_ARGB_PRE)));
        btnSendMsg.setVerticalTextPosition(JButton.CENTER);
        btnSendMsg.setHorizontalTextPosition(JButton.CENTER);
        btnSendMsg.setFont(MetroStyle.SMALL_BUTTON_FONT);
        getRootPane().setDefaultButton(btnSendMsg);

        initLayout();

        setResizable(true);
        pack();
        setLocationRelativeTo(null);
    }

    private void initLayout() {
        setLayout(new BorderLayout(5, 5));

        add(makeFriendInfoPanel(), BorderLayout.NORTH);

        add(makeChatDisplayPn());

        add(makeChatInputPn(), BorderLayout.SOUTH);
    }

    private JPanel makeFriendInfoPanel() {
        JPanel mainPn = new JPanel(new BorderLayout(5, 5));

        JLabel friendAva = new JLabel(friend.getAvatar());
        mainPn.add(friendAva, BorderLayout.WEST);

        JPanel friendInfoPn = new JPanel(new GridBagLayout());
        GridBagConstraints cons = new GridBagConstraints();
        cons.fill = GridBagConstraints.BOTH;
        cons.anchor = GridBagConstraints.FIRST_LINE_START;
        cons.insets = new Insets(3, 3, 3, 3);

        cons.gridx = 0;
        cons.gridy = 0;
        JLabel label = new JLabel(friend.getDisplayName());
        label.setFont(SegoeFont.getSegoeUIFont("bold",
                15f));
        friendInfoPn.add(label, cons);

        cons.gridy++;
        friendInfoPn.add(new JLabel("(" + friend.getUsername() + ")"), cons);

        cons.gridy++;
        ImageIcon imgStatus;
        String status;
        if (friend.isStatus()) {
            imgStatus = Util.makeIcon("available");
            status = "Online";
        } else {
            imgStatus = Util.makeIcon("offline");
            status = "Offline";
        }
        label = new JLabel(status);
        label.setIcon(imgStatus);
        friendInfoPn.add(label, cons);

        JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEADING));
        panel.add(friendInfoPn);

        mainPn.add(panel);
        mainPn.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

        return mainPn;
    }

    private JPanel makeChatDisplayPn() {
        JPanel mainPn = new JPanel();

        JScrollPane scrollPane = new JScrollPane(chatDisplay);
        chatDisplay.setPreferredSize(new Dimension(400, 300));

        mainPn.add(scrollPane);

        mainPn.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

        return mainPn;
    }

    private JPanel makeChatInputPn() {
        JPanel mainPn = new JPanel(new BorderLayout(5, 5));

        JScrollPane scrollPane = new JScrollPane(chatInput);
        mainPn.add(scrollPane);

        JPanel currentUserPn = new JPanel(new BorderLayout(5, 5));
        JLabel label = new JLabel(currentUserAvatar);
        label.setBorder(BorderFactory.createEmptyBorder());
        currentUserPn.add(new JLabel(currentUserAvatar));

        currentUserPn.add(btnSendMsg, BorderLayout.SOUTH);

        mainPn.add(currentUserPn, BorderLayout.EAST);

        mainPn.add(lblTextCount, BorderLayout.NORTH);

        mainPn.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

        return mainPn;
    }

    public void insertMessage(String displayName, String message) {
        try {
            StyledDocument docStyle = (StyledDocument) chatDisplay.getDocument();

            Style style = docStyle.addStyle("ChatStyle", null);
            StyleConstants.setBold(style, true);
            String chat = displayName + " [" + new Date().toString() + "]:\n";
            docStyle.insertString(docStyle.getLength(), chat, style);
            StyleConstants.setBold(style, false);
            docStyle.insertString(docStyle.getLength(), message + "\n", style);
            chatDisplay.setCaretPosition(docStyle.getLength());

        } catch (BadLocationException ex) {
            Logger.getLogger(Dialog_Chat.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void initListener() {
        chatInput.addKeyListener(this);
        btnSendMsg.addActionListener(this);
        this.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                // Method
                engine.removeDialogChat(friend.getUid());
                Dialog_Chat.this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
            }
        });
    }

    /**
     * *************************************************************************
     * Controller part
     * *************************************************************************
     */
    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            // 'Enter' to send and 'Shift + Enter' to start new line
            if (e.isShiftDown()) {
                // 'Shift + Enter' event
                addNewLine();
            } else {
                btnSendMsg.doClick();
            }
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
        checkChatInputLength();
    }

    private void checkChatInputLength() {
        int length = chatInput.getText().length();
        lblTextCount.setText(length + "/500");

        if (length > 500) {
            String chatString = chatInput.getText().substring(0, 500);
            chatInput.setText(chatString);
        }
    }

    private void addNewLine() {
        chatInput.append("\n");
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        String cmd = e.getActionCommand();

        if (cmd.equalsIgnoreCase("send")) {
            engine.sendMessage(engine.getClient().getUID(), friend.getUid(), chatInput.getText());
        }
        chatInput.setText("");
    }

    @Override
    public void update(Observable o, Object arg) {
        String[] args = ((String) arg).split(":");
        if (args.length >= 2) {
            insertMessage(args[0], args[1]);
        }
    }
}
